﻿//-----------------------------------------------------------------------
// <copyright file="Program.cs" company="Paul V. Borza">
// http://fastget.codeplex.com/license
// </copyright>
//-----------------------------------------------------------------------

namespace FastGet
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;
    using System.Net;

    public static class Program
    {
        private static string filePath = "localhost.txt";

        private static string cachePath = "cache.txt";

        private static int bucketSize = 5000;

        private static int iterationCount = 1;

        private static int connectionCount = 50;

        private static int timeout = 10000;

        public static void Main(string[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            if (!TryParseArgs(args))
            {
                PrintUsage();

                return;
            }

            CounterManager.Setup();
            RequestManager.Setup(connectionCount);

            var cache = FileManager.ReadCache(cachePath);

            var filePosition = 0L;

            var outputPath = "output";

            while (filePosition != -1)
            {
                var queue = FileManager.Read(filePath, ref filePosition, iterationCount, bucketSize, timeout);

                Console.WriteLine("Started new bucket.");

                RequestManager.Start(queue, cache, outputPath);
            }

#if DEBUG
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
#endif
        }

        private static bool TryParseArgs(string[] args)
        {
            if (args.Length == 0)
            {
                return false;
            }

            foreach (var arg in args)
            {
                if (arg.StartsWith("-file:", StringComparison.OrdinalIgnoreCase))
                {
                    // -file:localhost.txt
                    filePath = arg.Substring("-file:".Length);
                }
                else if (arg.StartsWith("-cache:", StringComparison.OrdinalIgnoreCase))
                {
                    // -cache:cache.txt
                    cachePath = arg.Substring("-cache:".Length);
                }
                else if (arg.StartsWith("-bucket:", StringComparison.OrdinalIgnoreCase))
                {
                    // -bucket:5000
                    if (!int.TryParse(arg.Substring("-bucket:".Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out bucketSize))
                    {
                        return false;
                    }
                }
                else if (arg.StartsWith("-iterations:", StringComparison.OrdinalIgnoreCase))
                {
                    // -iterations:1
                    if (!int.TryParse(arg.Substring("-iterations:".Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out iterationCount))
                    {
                        return false;
                    }
                }
                else if (arg.StartsWith("-connections:", StringComparison.OrdinalIgnoreCase))
                {
                    // -connections:50
                    if (!int.TryParse(arg.Substring("-connections:".Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out connectionCount))
                    {
                        return false;
                    }
                }
                else if (arg.StartsWith("-timeout:", StringComparison.OrdinalIgnoreCase))
                {
                    // -timeout:50
                    if (!int.TryParse(arg.Substring("-timeout:".Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out timeout))
                    {
                        return false;
                    }
                }
                else if (arg.Equals("-perfmon", StringComparison.OrdinalIgnoreCase))
                {
                    // -perfmon
                    StartPerfMon();
                }
                else if (arg.Equals("-debug", StringComparison.OrdinalIgnoreCase))
                {
                    // -debug
                    StartDebugger();
                }
                else if (arg.Equals("-help", StringComparison.OrdinalIgnoreCase))
                {
                    // -help
                    return false;
                }
            }

            return true;
        }

        [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Justification = "Will be fixed in future releases.")]
        private static void PrintUsage()
        {
            Console.WriteLine("See http://fastget.codeplex.com/documentation" + Environment.NewLine +
                Environment.NewLine +
                "fastget.exe" + Environment.NewLine +
                "  -file:localhost.txt   Sets the file which contains all requests." + Environment.NewLine +
                "  -cache:cache.txt      Sets the cache of already made requests." + Environment.NewLine +
                "  -bucket:5000          Sets the size of the bucket to split the input file to." + Environment.NewLine +
                "  -iterations:1         Sets the number of times to iterate over all requests." + Environment.NewLine +
                "  -connections:50       Sets the number of connections to do in parallel." + Environment.NewLine +
                "  -timeout:5000         Sets the timeout for each request in milliseconds." + Environment.NewLine +
                "  -perfmon              Displays the fastget.exe performance counters in perfmon.exe" + Environment.NewLine +
                "  -debug                Allows the Visual Studio debugger to attach to the process." + Environment.NewLine +
                "  -help                 Prints this short usage manual." + Environment.NewLine +
                Environment.NewLine +
                "localhost.txt" + Environment.NewLine +
                "  -url:http://localhost/ -method:GET" + Environment.NewLine +
                "  -url:http://localhost/ -method:POST -header:Content-Type:application/x-www-form-urlencoded -body:name=abc&address=123" + Environment.NewLine);

            Console.Out.Flush();
        }

        private static void StartPerfMon()
        {
            var perfmon = new Process()
            {
                // *.perfmoncfg is associated with perfmon.exe
                StartInfo = new ProcessStartInfo("Counters.perfmoncfg")
            };

            perfmon.Start();
        }

        private static void StartDebugger()
        {
            Debugger.Launch();
        }
    }
}
